<?php
function dummy() {
return true;
}
include($_SERVER['DOCUMENT_ROOT'].'/config.php');
Class database {
	public $connection;
	public $collection;
	public $id;
	public $item;
	public $sort;
	public $skip;
	public $limit;
	public $slice;
	public $fields;
	protected $memcache;
	protected $cachetime;
	protected $cachekey;
	public function __construct() {
     	$this->connection = new Mongo("mongodb:///tmp/mongodb-27017.sock",array("persist" => session_id()));
		//$this->memcache = new Memcache;
		//$this->memcache->connect('127.0.0.1', 11211);
    }
	public function db($db)
	{
		$this->db = $this->connection->selectDB($db);
		return $this;
	}
	public function index() {
		$this->collection->ensureIndex($this->criteria);	
	}
	public function uniqueIndex() {

	$this->collection->ensureIndex($this->criteria, array("unique" => 1, "dropDups" => 1));	
	}
	public function cache() {
		$this->memcache=true;
		return $this;
	}
	public function error() {
	$this->db->resetError();
	return $this->db->lastError();	
	}
	public function close() {
		$this->connection->close();	
		return $this;
	}
	public function slice() {
		$this->slice=true;
		return $this;
	}
	public function fields($f) {
		$this->fields=(object)$f;
		return $this;
	}
	public function count() {
		$this->count=$this->collection->count($this->criteria);	
		return $this->count;
	}
	public function collection($collection)
	{
		$this->collection = $this->db->selectCollection($collection);
		return $this;
	}
	public function remove() {
		$this->collection->remove($this->criteria, array('safe' => true));
		return $this;	
	}
	
	public function criteria($criteria) {
		$this->criteria=$criteria;
		return $this;
	}
	public function command() {
    	return $this->findOne($this->criteria);
	}
	public function sort($s) {
		
		if(is_array($s)) {
			$this->sort=$s;
			
		} else {
			$this->sort=array('_id'=>1);// natural
			
		}
		return $this;
	}
	public function skip($s) {
		
		$this->skip= ($s>0) ? $s : 0;
		return $this;
	}
	public function limit($l) {
		$this->limit=intval($l);
		return $this;
	}
	public function findAll() {
		if($this->memcache) {
		
		
		$mcoutput=$this->getMC();
		if(is_array($mcoutput)) {
			$mcoutput['cached']='cached';
			return $mcoutput;	
		}
		}
		
		if($this->slice) {
			$cursor = $this->collection->find($this->criteria,$this->fields);	
		} else {
			$cursor = $this->collection->find($this->criteria);	
		}
		$output='';
		$output['num_results']=$cursor->count();
		$i=0;
		foreach($cursor as $row) {
			$output['results'][]=$row;
			$i++;	
		}
		$output['this_num']=$i;
		if($this->memcache && !is_array($mcoutput)) {
			
		$this->addMC($this->cachekey,$output,$this->cachetime); 
		}
		array_walk($output, array($this,'unclean'));
		return $output;
	}
	public function find() {
		if($this->memcache) {
		
		
		$mcoutput=$this->getMC();
		if(is_array($mcoutput)) {
			$mcoutput['cached']='cached';
			return $mcoutput;	
		}
		}
		if($this->slice) {
			$cursor = $this->collection->find($this->criteria,$this->fields);	
		} else {
			$cursor = $this->collection->find($this->criteria);	
		}	
		$cursor->sort($this->sort)->skip($this->skip)->limit($this->limit);
		
		$output='';
		$output['cached']=false;
		$output['num_results']=$cursor->count();
		$i=0;
		foreach($cursor as $row) {
			$output['results'][]=$row;
			$i++;	
		}
		$output['this_num']=$i;
		if($this->memcache && !is_array($mcoutput)) {
			
		$this->addMC($this->cachekey,$output,$this->cachetime); 
		}
		
		array_walk($output, array($this,'unclean'));
		return $output;
	}
	public function findNs() {
		if($this->memcache) {
		
		
		$mcoutput=$this->getMC();
		if(is_array($mcoutput)) {
			$mcoutput['cached']='cached';
			return $mcoutput;	
		}
		}
		
		
		if($this->slice) {
			$cursor = $this->collection->find($this->criteria,$this->fields);	
		} else {
			$cursor = $this->collection->find($this->criteria);	
		}
		
		
		$output='';
		$output['num_results']=$cursor->count();
		$i=0;
		foreach($cursor as $row) {
			$output['results'][]=$row;
			$i++;	
		}
		$output['this_num']=$i;
		array_walk($output, array($this,'unclean'));
		return $output;
	}
	public function findNl() {
		if($this->memcache) {
		
		
		$mcoutput=$this->getMC();
		if(is_array($mcoutput)) {
			$mcoutput['cached']='cached';
			return $mcoutput;	
		}
		}
		
		
		if($this->slice) {
			$cursor = $this->collection->find($this->criteria,$this->fields);	
		
		} else {
			$cursor = $this->collection->find($this->criteria);	
		}
		
		$cursor->sort($this->sort);
		$output='';
		$output['cached']="not-cached";
		$output['num_results']=$cursor->count();
		$i=0;
		foreach($cursor as $row) {
			$output['results'][]=$row;
			$i++;	
		}
		$output['this_num']=$i;
		if($this->memcache && !is_array($mcoutput) && $output['num_results']>=1) {
		
		$this->addMC($this->cachekey,$output,$this->cachetime); 
		}
		
		
		array_walk($output, array($this,'unclean')); 	
		return $output;
		
	}
		public function cachekey($key) {
			$this->cachekey=$key;
			return $this;
		}
		public function expireCache($key) {
			$mc = new Memcached();
			$mc->addServer('localhost', 11211);	
			$mc->delete($key);
			return $this;
		}
		public function addMC($key,$value,$time) {
		$mc = new Memcached();
		$mc->addServer('localhost', 11211); 
		$cachekey=(empty($this->cachekey)) ? $this->collection.".".$key : $this->cachekey;
		
		$mc->set($cachekey, $value,  $time); 
		return $this;	
	}
	
	
	public function setMC($key,$value,$time) {
		$mc = new Memcached();
		$mc->addServer('localhost', 11211);
		$cachekey=(empty($this->cachekey)) ? $this->collection.".".$key : $this->cachekey;
		$mc->set($cachekey, $value, $time); 
		return $this;	
	}
	public function getMC() {
		$mc = new Memcached();
		$mc->addServer('localhost', 11211);	
		$criteria=$this->criteria;
		$mckey=(string)$criteria['_id'];
		$cachekey=(empty($this->cachekey)) ? $this->collection.".".$mckey : $this->cachekey;
		$j=$mc->get($cachekey); 
		if(is_array($j)) {
			$j['cached']='true';
		return $j;
		}
	}
	
	public function findOne() {
		if($this->memcache) {
			$row=$this->getMC();
			$this->close();
			if(is_array($row)) {
				return $row; 
			
			}
		}
		if(is_array($this->criteria)) {
			$row=$this->collection->findOne($this->criteria);
		} else {
			$row=$this->collection->findOne();	
		}
		$row['cached']='false';
		$this->close();
		$this->addMC((string)$row['_id'],$row,$this->cachetime);
		array_walk($row, array($this,'unclean')); 
		return $row;
	}
	public function debug() {
		echo('<pre>');
		echo(json_encode($this->criteria));
		echo('</pre>');	
		return $this;
	}
	public function id() {
		$this->id=new MongoId();
		$this->close();
		return $this;	
	}
	public function cachetime($time) {
		$this->cachetime=($time) ? $time : 300; // defaults to 5 mins
		return $this;		
	}
	public function insert() {
		if(!$this->criteria['_id']) { 
		$this->id(); 
		$this->criteria['_id']=$this->id;
		}
		unset($this->id);
		$criteria=$this->criteria;
		array_walk($criteria, array($this,'cleanup')); 		
		$this->criteria=$criteria;
		$criteria=$this->criteria;
		$this->collection->insert($this->criteria);
		if($this->memcache) {
			$this->addMC((string)$id,$crit,$this->cachetime);
		}
		
		
		unset($this->criteria);
		return $criteria;//
	}
	function cleanup(&$item,$key) {
		
		if( is_array($item) )
       	 {
        	    array_walk($item,array($this,'cleanup'));
       	 }	else {
			
			if(is_object($item)) {
				$item=$item;	
			}
			 else {
			$item=mb_convert_encoding($item,'UTF-8','auto');	
			if(is_string($item)) {
				$item=str_replace("","",$item);	
			}
			if(is_numeric($item)) {
				if(strpos($item,".")!==false) { // crude test for a decimal point inside the integer
				$item=floatval($item);	
				} else {
				$item=intval($item);
				}
			}
		} // end object
			
		 $this->criteria[$key]=$item;
		 }
	}
	function unclean(&$item,$key) {
		if( is_array($item) )
       	 {
        	    array_walk($item, array($this,'unclean'));
       	 }	else {
				
			$item=stripslashes($item);
			}		 
		 }
	
	public function update($id) {
		$_id=array('_id'=>new MongoId($id)); 
		$criteria=$this->criteria;
		array_walk($criteria, array($this,'cleanup')); 		
		$this->criteria=$criteria;		
		if($this->memcache) {
			$this->setMC((string)$id,$this->criteria,$this->cachetime);
		}
		
		$this->collection->update($_id,$this->criteria);
		return $this;
	}
	public function updateMultiple($id) {
		
		$this->collection->update($id,$this->criteria, array("upsert" => true));
		unset($this->criteria);
		return $this;	
	}
	
	function __destruct() {
      $this->close();
   }
	public function addtocache($args) {
		
		$this->cachetime=$args['cache_time'];
		
		if($memcache->set($args['obj']['key'],$args['obj']['val'],$args['obj']['flag'],$this->cachetime)) {
			return $this;
		}
		else {
			return false;	
		}
	}
	public function checkcache($key) {
		
		
		$obj=$memcache->get($key);
		if($obj) {
			return $obj;	
		} else {
			return false;	
		}
	}
}
?>